/*
 * Copyright (C) 2013 Daniel Wasilew <daniel.wasilew@codeminer.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.codeminer.parts.specification.html;

import de.wusel.picotask.xml.element.XMLElement;
import org.codeminer.parts.specification.CreationException;
import org.codeminer.parts.specification.DocCreator;
import org.codeminer.parts.specification.ParserFileLocations;
import org.codeminer.parts.specification.general.EmptyLinePart;
import org.codeminer.parts.specification.general.FilePart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

/**
 * User: Daniel Wasilew <daniel.wasilew@codeminer.org>
 * Date: 03.03.13
 * Time: 09:17
 */
public class HTMLDocumentationCreator implements DocCreator {
    private static final Logger log = LoggerFactory.getLogger(HTMLDocumentationCreator.class);
    private final ParserFileLocations locations;
    private final List<FilePart> startDocumentation = new ArrayList<>();
    private PrintWriter writer;

    private final Map<File, List<XMLElement>> elementsByFolder = new HashMap<>();

    public HTMLDocumentationCreator(ParserFileLocations locations) {
        this.locations = locations;
        this.startDocumentation.add(new HeadPart());
        this.startDocumentation.add(new EmptyLinePart());
        this.startDocumentation.add(new DefaultBodyPart());
        this.startDocumentation.add(new EmptyLinePart());
    }

    @Override
    public void start() throws CreationException {
        File outputFile = new File(locations.getHTMLDocumentationOutputDirectory(), "index.html");
        log.info("trying to delete [{}]", outputFile);
        boolean delete = !outputFile.exists() || outputFile.delete();
        if (!delete)
            throw new CreationException("could not delete outputFile");
        try {
            outputFile.createNewFile();
        } catch (IOException e) {
            throw new CreationException("could not create [" + outputFile.getAbsolutePath() + "]");
        }
        try {
            writer = new PrintWriter(outputFile);
            for (FilePart filePart : startDocumentation) {
                filePart.writeTo(writer, null);
            }
        } catch (FileNotFoundException ex) {
            throw new CreationException(ex);
        }

    }

    @Override
    public void create(XMLElement element, File file) throws CreationException {
        File parent = file.getParentFile();
        List<XMLElement> xmlElements = this.elementsByFolder.get(parent);
        if (xmlElements == null) {
            xmlElements = new LinkedList<>();
            this.elementsByFolder.put(parent, xmlElements);
        }
        xmlElements.add(element);

    }

    @Override
    public void end() throws CreationException {
        if (writer == null) {
            throw new CreationException("Writer not initialized");
        }
        try {
            //first: write tab control for all folders
            writer.println("<div>");
            writeTabControl();
            //second:
            writeTabContent();
            writer.println("</div>");
            HTMLEndPart part = new HTMLEndPart();
            part.writeTo(writer, null);
        } finally {
            writer.close();
        }
    }

    private void writeTabContent() {
        String active =" active in";
        writer.println("<div class=\"tab-content\">");
        for (Map.Entry<File, List<XMLElement>> fileListEntry : elementsByFolder.entrySet()) {
            File current = fileListEntry.getKey();
            if (current.equals(this.locations.getSpecificationDirectory())) {
                writer.println("<div class=\"tab-pane fade"+active+"\" id=\"global\">");
            } else {
                String pathName = current.getName();
                writer.println("<div class=\"tab-pane fade"+active+"\" id=\"" + pathName.toLowerCase() + "\">");

            }
            active = "";
            List<XMLElement> value = fileListEntry.getValue();
            for (XMLElement xmlElement : value) {
                ActionHTMLPart part = new ActionHTMLPart();
                part.writeTo(writer, xmlElement);
                EmptyLinePart emptyLinePart = new EmptyLinePart();
                emptyLinePart.writeTo(writer, xmlElement);
            }
            writer.println("</div>");
        }
        writer.println("</div>");

    }

    private void writeTabControl() {
        /**
         * <ul id="actionTab" class="nav nav-tabs">
         <li class="active"><a href="#global" data-toggle="tab">Global</a></li>
         <li class=""><a href="#subfolder" data-toggle="tab">subfolder</a></li>
         </ul>
         */
        writer.println("<ul id=\"actionTab\" class=\"nav nav-tabs\">");

        String active = "active";
        for (File current : elementsByFolder.keySet()) {
            if (current.equals(this.locations.getSpecificationDirectory())) {
                writer.println("<li class=\"" + active + "\"><a href=\"#global\" data-toggle=\"tab\">Global</a></li>");
            } else {
                String pathName = current.getName();
                writer.println("<li class=\"" + active + "\"><a href=\"#" + pathName.toLowerCase() + "\" data-toggle=\"tab\">" + pathName + "</a></li>");
            }
            active = "";
        }
        writer.println("</ul>");

    }
}
